/**
 * 
 */
package com.cn.practice.decorator;

/**
 * 装饰者模式-装饰者模式的核心就是对外装饰却不改变原有方法
 * 类似包装快递-衣服用塑料袋包住，在外面填充泡沫，再包上纸箱
 * 但是这些包装却对衣服无影响
 * @author zhangyang
 *
 */
public class DecoratorPractice2 {
public static void main(String[] args) {
	//初始化圆通快递
	YuanTong yuanTong = new YuanTong();
	//将圆通快递报纸包装
	PaperDecorator paperDecorator = new PaperDecorator(yuanTong);
	System.out.println(paperDecorator.name);
	//在包装一层棉布
	CottonDecorator decorator = new CottonDecorator(paperDecorator);
	System.out.println(decorator.name);
	System.out.println(decorator.cost());
	/**
	 * FilterInputStream都是使用的包装模式实现
	 * 底层还是inputStream 但是外面套上不同的包装形成不同种类的流类型
	 */
}
}

/**
 * 装饰模式核心要点 包装类继承且聚合原有类
 * @author zhangyang
 *
 */

/**
 * 包裹类-所有快递的基础类
 * @author zhangyang
 *
 */
abstract class Package{
	String name;
	float price;
	/**
	 * 抽象方法 用以计算快递打包费用
	 * @return
	 */
	abstract float cost();
}

/**
 * 圆通快递-不加包装
 * @author zhangyang
 *
 */
class YuanTong extends Package{

	public YuanTong() {
		this.name="圆通";
		this.price=10f;
	}
	@Override
	float cost() {
		// TODO Auto-generated method stub
		return this.price;
	}
	
}

/**
 * 顺丰快递-不加包装
 * @author zhangyang
 *
 */
class ShunFeng extends Package{

	public ShunFeng() {
		this.name="顺丰";
		this.price=15f;
	}
	@Override
	float cost() {
		// TODO Auto-generated method stub
		return this.price;
	}
	
}

/**
 * 快递包装抽象类-包装类
 * @author zhangyang
 *
 */
abstract class DecoratorPackage extends Package{
	Package pakg;
	
	
	public DecoratorPackage(Package pakg) {
		super();
		this.pakg = pakg;
	}

	@Override
	float cost() {
		// TODO Auto-generated method stub
		return pakg.cost()+this.price;
	}
	
	public String getName() {
		return this.name;
	}
}

class PaperDecorator extends DecoratorPackage{

	/**
	 * @param pakg
	 */
	public PaperDecorator(Package pakg) {
		super(pakg);
		// TODO Auto-generated constructor stub
		this.name=pakg.name+"_"+"报纸包装";
		this.price=1f;
	}
	
}

class CottonDecorator extends DecoratorPackage{

	/**
	 * @param pakg
	 */
	public CottonDecorator(Package pakg) {
		super(pakg);
		// TODO Auto-generated constructor stub
		this.name=pakg.name+"_"+"棉布包装";
		this.price=3f;
	}
	
}